import 'package:flutter/material.dart';

class StatisticsChart extends CustomPainter {
  double min = 0.0;
  double max = 1000;
  int vGapCount = 4;
  double xAxisLabelH = 30;
  double yAxisLabelW = 40;
  double yAxisTitleGap = 10;
  double paddingLeft = 10;
  double paddingRight = 10;

  double dataMarginLeft = 5;
  double dataMarginRight = 5;

  //表示数据区域绘制范围
  double _dataStartX = 0;
  double _dataEndX = 0;
  double _dataStartY = 0;
  double _dataEndY = 0;

  List<double> barData = [
    789.0,
    300.0,
    400.0,
    500.0,
    350,
    420,
    800,
    983,
    1000,
    134,
    888,
    640
  ];

  /// 画图的笔
  Paint _painter = Paint()
    ..strokeWidth = 1.2
    ..style = PaintingStyle.stroke;

  /// 画文字的笔
  TextPainter _textPainter = TextPainter(
    textDirection: TextDirection.ltr,
    maxLines: 1,
  );

  @override
  void paint(Canvas canvas, Size size) {
    // 超过父组件的绘制内容都会被剪切掉
    Rect rect = Offset.zero & size;
    canvas.clipRect(rect);
    // 设置背景颜色
    _painter.color = Colors.white;
    _painter.style = PaintingStyle.fill;
    canvas.drawRect(rect, _painter);

    print("width=${size.width},height=${size.height}");
    _drawLeftYAxis(canvas, size);
    _drawRightYAxis(canvas, size);
    _drawYCrossLine(canvas, size);

    _drawData(canvas, size);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }

  _drawLeftYAxis(Canvas canvas, Size size) {
    double y = 0;
    double x = paddingLeft;

    //绘制左侧y轴说明
    _textPainter.text = TextSpan(
        text: '金额(万)',
        style: TextStyle(color: Color(0xFF999999), fontSize: 10));
    _textPainter.layout(maxWidth: yAxisLabelW);
    _textPainter.paint(canvas, Offset(x, y));
    y += (yAxisTitleGap + _textPainter.height);
    double vGap = (size.height - y - xAxisLabelH) / vGapCount;
    print("vGap=$vGap");
    double vUnit = (max - min) / vGapCount;

    for (int i = 0; i <= vGapCount; i++) {
      _textPainter.text = TextSpan(
          text: '${max - i * vUnit}',
          style: TextStyle(color: Color(0xFF999999), fontSize: 10));
      _textPainter.layout(maxWidth: yAxisLabelW);
      _textPainter.paint(canvas, Offset(x, y));
      y += vGap;
    }

    // _textPainter.text = TextSpan(
    //     text: '$min', style: TextStyle(color: Color(0xFF999999), fontSize: 10));
    // _textPainter.layout(maxWidth: yAxisLabelW);
    // _textPainter.paint(
    //     canvas, Offset(x, size.height - xAxisLabelH - _textPainter.height));
  }

  _drawRightYAxis(Canvas canvas, Size size) {
    double y = 0;
    double x = size.width - paddingRight;

    //绘制左侧y轴说明
    _textPainter.text = TextSpan(
        text: '笔数(笔)',
        style: TextStyle(color: Color(0xFF999999), fontSize: 10));
    _textPainter.layout(maxWidth: yAxisLabelW);
    _textPainter.paint(canvas, Offset(x - _textPainter.width, y));
    y += (yAxisTitleGap + _textPainter.height);
    double vGap = (size.height - y - xAxisLabelH) / vGapCount;
    print("vGap=$vGap");
    double vUnit = (max - min) / vGapCount;

    for (int i = 0; i <= vGapCount; i++) {
      _textPainter.text = TextSpan(
          text: '${max - i * vUnit}',
          style: TextStyle(color: Color(0xFF999999), fontSize: 10));
      _textPainter.layout(maxWidth: yAxisLabelW);
      _textPainter.paint(canvas, Offset(x - _textPainter.width, y));

      y += vGap;
    }

    // _textPainter.text = TextSpan(
    //     text: '$min', style: TextStyle(color: Color(0xFF999999), fontSize: 10));
    // _textPainter.layout(maxWidth: yAxisLabelW);
    // _textPainter.paint(
    //     canvas,
    //     Offset(x - _textPainter.width,
    //         size.height - xAxisLabelH - _textPainter.height));
  }

  _drawYCrossLine(Canvas canvas, Size size) {
    _textPainter.text = TextSpan(
        text: '笔数(笔)',
        style: TextStyle(color: Color(0xFF999999), fontSize: 10));
    _textPainter.layout();

    double startX = paddingLeft + yAxisLabelW;
    double endX = size.width - paddingRight - yAxisLabelW;

    _dataStartX = startX;
    _dataEndX = endX;

    print("textHeight=${_textPainter.height}");
    double y = yAxisTitleGap + _textPainter.height;

    _textPainter.text = TextSpan(
        text: '$max', style: TextStyle(color: Color(0xFF999999), fontSize: 10));
    _textPainter.layout();
    print("max -> textHeight=${_textPainter.height}");
    double dy = _textPainter.height / 2 - _painter.strokeWidth / 2;
    print("dy=$dy");
    double vGap = (size.height - y - xAxisLabelH) / vGapCount;

    _dataStartY = y + dy;

    _painter.color = Color(0xFFDDDDDD);
    for (int i = 0; i <= vGapCount; i++) {
      canvas.drawLine(Offset(startX, y + dy), Offset(endX, y + dy), _painter);
      if (i == vGapCount) _dataEndY = y + dy;
      y += vGap;
    }
  }

  _drawData(Canvas canvas, Size size) {
    print(
        "_dataStartX=$_dataStartX,_dataEndX=$_dataEndX,_dataStartY=$_dataStartY,_dataEndY=$_dataEndY");
    double xBarGap = 10;

    double barWidth = (_dataEndX -
            _dataStartX -
            (barData.length - 1) * xBarGap -
            dataMarginLeft -
            dataMarginRight) /
        barData.length;
    double yValueUnit = (_dataEndY - _dataStartY) / (max - min);

    double x = _dataStartX + dataMarginLeft;
    double zeroY = _dataEndY - (0 - min) * yValueUnit;
    double xAxisLabelY = _dataEndY + 5;
    _painter.color = Color(0xFF009669);
    Offset? p1;
    for (int i = 0; i < barData.length; i++) {
      double yValue = barData[i] * yValueUnit;
      Rect rect = Rect.fromLTWH(x, zeroY - yValue, barWidth, yValue);
      _painter.color = Color(0xFF009669);
      canvas.drawRect(rect, _painter);

      //绘制点
      Offset p2 = Offset(x + barWidth / 2, zeroY - yValue);
      _painter.color = Color(0xFFFFAD00);
      canvas.drawCircle(p2, 3, _painter);
      if (p1 != null) {
        canvas.drawLine(p1, p2, _painter);
      }
      p1 = p2;

      //绘制x轴标签文本
      _textPainter.text = TextSpan(
          text: '${i + 1}月',
          style: TextStyle(fontSize: 10, color: Color(0xFF999999)));
      _textPainter.layout();
      _textPainter.paint(canvas,
          Offset(x + barWidth / 2 - _textPainter.width / 2, xAxisLabelY));
      x += (xBarGap + barWidth);
    }
  }
}
